package ch.exm.storm.conditions;

import ch.exm.storm.query.relational.RelationalQuery;

public class In extends AbstractSimpleCondition {
	
	private Object[] inArguments;

	public In(Object first, Object... second) {
		this.inArguments = second;
		arguments = new Object[second.length+1];
		arguments[0] = first;
		for (int i = 0; i < second.length; i++) arguments[i+1] = second[i];
	}
	
	@Override
	public boolean evaluateRelationalCondition(RelationalQuery query, boolean inverse) {
		whereCondition = new StringBuilder(); 
		if (!isRelationalArgument(query, arguments[0])) return false;
		whereCondition.append(inverse ? getInverseConditionKeyword() : getConditionKeyword());
		
		boolean first = true;
		for (Object inObj : inArguments) {
			if (first) first = false;
			else whereCondition.append(", ");
			if (!isRelationalArgument(query, inObj)) return false;
		}

		whereCondition.append(")");
		return true;
	}
	
	@Override
	public boolean matches(Object object) {
		Object firstArgument = evaluteArgumentOn(arguments[0], object);
		for (Object inObj : inArguments) if (matches(firstArgument, evaluteArgumentOn(inObj, object))) return true;
		return false;		
	}
	
	public boolean matches(Object firstValue, Object secondValue) {
		if (firstValue == null && secondValue == null) return true;
		if (firstValue == null || secondValue == null) return false;
		return firstValue.equals(secondValue);
	}

	@Override
	protected String getConditionKeyword() {
		return (" in (");
	}
	
	@Override
	protected String getInverseConditionKeyword() {
		return (" not in (");
	}

	public static In isIn(Object first, Object... second) {
		return new In(first, second);
	}
}
